home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ptoc / part11 < prev    next >
Encoding:
Internet Message Format  |  1987-07-28  |  57.1 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i075:  Pascal to C translator, Part11/12
  5. Message-ID: <728@uunet.UU.NET>
  6. Date: 30 Jul 87 00:31:02 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2280
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
  12. Posting-number: Volume 10, Issue 75
  13. Archive-name: ptoc/Part11
  14.  
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 11 (of 12)."
  23. # Contents:  ptc.p.4
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'ptc.p.4' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'ptc.p.4'\"
  27. else
  28. echo shar: Extracting \"'ptc.p.4'\" \(54467 characters\)
  29. sed "s/^X//" >'ptc.p.4' <<'END_OF_FILE'
  30. X                    end
  31. X            until    tq = nil;
  32. X        555:
  33. X            writeln(';');
  34. X            if tp^.tt = nvarpar then
  35. X                if tp^.tbind^.tt = nconfarr then
  36. X                    begin
  37. X                    indent;
  38. X                    etypedef(tp^.tbind^.tindtyp);
  39. X                    write(tab1);
  40. X                    tq := tp^.tbind^.tcindx^.thi;
  41. X                    printid(tq^.tsym^.lid);
  42. X                    writeln(';')
  43. X                    end;
  44. X            tp := tp^.tnext
  45. X            end
  46. X    end;    (* evar *)
  47. X
  48. X    (*    Emit code for a statment.                *)
  49. X    procedure estmt(tp : treeptr);
  50. X
  51. X    var    tq    : treeptr;
  52. X        locid1,
  53. X        locid2    : idptr;
  54. X        stusd    : boolean;
  55. X        opc1,
  56. X        opc2    : char;
  57. X
  58. X        (*    Emit typename for with-variable.        *)
  59. X        procedure ewithtype(tp : treeptr);
  60. X
  61. X        var    tq    : treeptr;
  62. X
  63. X        begin
  64. X            tq := typeof(tp);
  65. X            write('struct ');
  66. X            printid(tq^.tuid)
  67. X        end;
  68. X
  69. X        (*    Emit code for a case-choise.        *)
  70. X        procedure echoise(tp : treeptr);
  71. X
  72. X        var    tq    : treeptr;
  73. X            i    : integer;
  74. X
  75. X        begin
  76. X            while tp <> nil do
  77. X                begin
  78. X                tq := tp^.tchocon;
  79. X                i := 0;
  80. X                indent;
  81. X                while tq <> nil do
  82. X                    begin
  83. X                    write('  case ');
  84. X                    conflag := true;
  85. X                    eexpr(tq);
  86. X                    conflag := false;
  87. X                    write(':');
  88. X                    i := i + 1;
  89. X                    tq := tq^.tnext;
  90. X                    if (tq = nil) or (i mod 4 = 0) then
  91. X                        begin
  92. X                        writeln;
  93. X                        if tq <> nil then
  94. X                            indent;
  95. X                        i := 0
  96. X                        end
  97. X                    end;
  98. X                increment;
  99. X                if tp^.tchostmt^.tt = nbegin then
  100. X                    estmt(tp^.tchostmt^.tbegin)
  101. X                else
  102. X                    estmt(tp^.tchostmt);
  103. X                indent;
  104. X                writeln('break ;');
  105. X                decrement;
  106. X                tp := tp^.tnext;
  107. X                if tp <> nil then
  108. X                    if tp^.tchocon = nil then
  109. X                        tp := nil
  110. X                end
  111. X        end;    (* echoise *)
  112. X
  113. X        (*    Rename all accessible record-fields to include    *)
  114. X        (*    pointer name.                    *)
  115. X        procedure cenv(ip : idptr; dp : declptr);
  116. X
  117. X        var    tp    : treeptr;
  118. X            sp    : symptr;
  119. X            np    : idptr;
  120. X            h    : hashtyp;
  121. X
  122. X        begin
  123. X            with dp^ do
  124. X              for h := 0 to hashmax - 1 do
  125. X                begin
  126. X                sp := ddecl[h];
  127. X                while sp <> nil do
  128. X                    begin
  129. X                    if sp^.lt = lfield  then
  130. X                        begin
  131. X                        np := sp^.lid;
  132. X                        tp := sp^.lsymdecl^.tup^.tup;
  133. X                        if (tp^.tup^.tt = nvariant) and
  134. X                            (tp^.tuid <> nil) then
  135. X                            np := mkconc('.',
  136. X                                tp^.tuid, np);
  137. X                        np := mkconc('>', ip, np);
  138. X                        sp^.lid := np
  139. X                        end;
  140. X                    sp := sp^.lnext
  141. X                    end
  142. X                end
  143. X        end;    (* cenv *)
  144. X
  145. X        (*    Emit identifiers for push/pop of global ptrs.    *)
  146. X        procedure eglobid(tp : treeptr);
  147. X
  148. X        var    j    : toknidx;
  149. X            w    : toknbuf;
  150. X
  151. X        begin
  152. X            gettokn(tp^.tsym^.lid^.istr, w);
  153. X            j := 1;
  154. X            if w[1] = '*' then
  155. X                j := 2;
  156. X            while w[j] <> chr(null) do
  157. X                begin
  158. X                write(w[j]);
  159. X                j := j + 1
  160. X                end
  161. X        end;
  162. X
  163. X    begin    (* estmt *)
  164. X        while tp <> nil do
  165. X            begin
  166. X            case tp^.tt of
  167. X              nbegin:
  168. X                begin
  169. X                if tp^.tup^.tt in [nbegin, nrepeat,
  170. X                        nproc, nfunc, npgm] then
  171. X                    indent;
  172. X                writeln('{');
  173. X                increment;
  174. X                estmt(tp^.tbegin);
  175. X                decrement;
  176. X                indent;
  177. X                write('}');
  178. X                if tp^.tup^.tt <> nif then
  179. X                    writeln
  180. X                end;
  181. X              nrepeat:
  182. X                begin
  183. X                indent;
  184. X                writeln('do {');
  185. X                increment;
  186. X                estmt(tp^.treptstmt);
  187. X                decrement;
  188. X                indent;
  189. X                write('} while (!(');
  190. X                eexpr(tp^.treptxp);
  191. X                writeln('));')
  192. X                end;
  193. X              nwhile:
  194. X                begin
  195. X                indent;
  196. X                write('while (');
  197. X                increment;
  198. X                eexpr(tp^.twhixp);
  199. X                stusd := setused;
  200. X                if tp^.twhistmt^.tt = nbegin then
  201. X                    begin
  202. X                    decrement;
  203. X                    write(') ');
  204. X                    estmt(tp^.twhistmt)
  205. X                    end
  206. X                else begin
  207. X                    writeln(')');
  208. X                    estmt(tp^.twhistmt);
  209. X                    decrement
  210. X                     end;
  211. X                setused := stusd or setused
  212. X                end;
  213. X              nfor:
  214. X                begin
  215. X                indent;
  216. X                if tp^.tincr then
  217. X                    begin
  218. X                    opc1 := '+';    (* increment variable *)
  219. X                    opc2 := '<'    (* test for <= *)
  220. X                    end
  221. X                else begin
  222. X                    opc1 := '-';    (* decrement variable *)
  223. X                    opc2 := '>';    (* test for >= *)
  224. X                     end;
  225. X                if not lazyfor then
  226. X                    begin
  227. X                    locid1 := mkvariable('B');
  228. X                    locid2 := mkvariable('B');
  229. X                    writeln('{');
  230. X                    increment;
  231. X                    indent;
  232. X                    tq := idup(tp^.tforid);
  233. X                    etypedef(tq^.tbind);
  234. X                    tq := typeof(tq^.tbind);
  235. X                    write(tab1);
  236. X                    printid(locid1);
  237. X                    write(' = ');
  238. X                    eexpr(tp^.tfrom);
  239. X                    writeln(',');
  240. X                    indent;
  241. X                    write(tab1);
  242. X                    printid(locid2);
  243. X                    write(' = ');
  244. X                    eexpr(tp^.tto);
  245. X                    writeln(';');
  246. X                    writeln;
  247. X                    indent;
  248. X                    write('if (');
  249. X                    if tq^.tt = nscalar then
  250. X                        begin
  251. X                        write('(int)(');
  252. X                        printid(locid1);
  253. X                        write(')')
  254. X                        end
  255. X                    else
  256. X                        printid(locid1);
  257. X                    write(' ', opc2, '= ');
  258. X                    if tq^.tt = nscalar then
  259. X                        begin
  260. X                        write('(int)(');
  261. X                        printid(locid2);
  262. X                        write(')')
  263. X                        end
  264. X                    else
  265. X                        printid(locid2);
  266. X                    writeln(')');
  267. X                    increment;
  268. X                    indent;
  269. X                    tp^.tfrom := newid(locid1);
  270. X                    tp^.tfrom^.tup := tp
  271. X                    end;
  272. X                write('for (');
  273. X                increment;
  274. X                eexpr(tp^.tforid);
  275. X                tq := typeof(tp^.tforid);
  276. X                write(' = ');
  277. X                eexpr(tp^.tfrom);
  278. X                write('; ');
  279. X                if lazyfor then
  280. X                    begin
  281. X                    if tq^.tt = nscalar then
  282. X                        begin
  283. X                        write('(int)(');
  284. X                        eexpr(tp^.tforid);
  285. X                        write(')')
  286. X                        end
  287. X                    else
  288. X                        eexpr(tp^.tforid);
  289. X                    write(' ', opc2, '= ');
  290. X                    if tq^.tt = nscalar then
  291. X                        begin
  292. X                        write('(int)(');
  293. X                        eexpr(tp^.tto);
  294. X                        write(')')
  295. X                        end
  296. X                    else
  297. X                        eexpr(tp^.tto)
  298. X                    end;
  299. X                write('; ');
  300. X                eexpr(tp^.tforid);
  301. X                if tq^.tt = nscalar then
  302. X                    begin
  303. X                    write(' = (');
  304. X                    eexpr(tq^.tup^.tidl);
  305. X                    write(')((int)(');
  306. X                    eexpr(tp^.tforid);
  307. X                    write(')', opc1, '1)')
  308. X                    end
  309. X                else
  310. X                    write(opc1, opc1);
  311. X                if not lazyfor then
  312. X                    begin
  313. X                    if tp^.tforstmt^.tt <> nbegin then
  314. X                        begin
  315. X                        (* create compund stmt *)
  316. X                        tq := mknode(nbegin);
  317. X                        tq^.tbegin := tp^.tforstmt;
  318. X                        tq^.tbegin^.tup := tq;
  319. X                        tp^.tforstmt := tq;
  320. X                        tq^.tup := tp
  321. X                        end;
  322. X                    (* find end of loop *)
  323. X                    tq := tp^.tforstmt^.tbegin;
  324. X                    while tq^.tnext <> nil do
  325. X                        tq := tq^.tnext;
  326. X                    (* add break stmt *)
  327. X                    tq^.tnext := mknode(nbreak);
  328. X                    tq := tq^.tnext;
  329. X                    tq^.tup := tp^.tforstmt;
  330. X                    tq^.tbrkid := tp^.tforid;
  331. X                    tq^.tbrkxp := newid(locid2);
  332. X                    tq^.tbrkxp^.tup := tq
  333. X                    end;
  334. X                if tp^.tforstmt^.tt = nbegin then
  335. X                    begin
  336. X                    decrement;
  337. X                    write(') ');
  338. X                    estmt(tp^.tforstmt)
  339. X                    end
  340. X                else begin
  341. X                    writeln(')');
  342. X                    estmt(tp^.tforstmt);
  343. X                    decrement
  344. X                     end;
  345. X                if not lazyfor then
  346. X                    begin
  347. X                    decrement;
  348. X                    decrement;
  349. X                    indent;
  350. X                    writeln('}')
  351. X                    end
  352. X                end;
  353. X              nif:
  354. X                begin
  355. X                indent;
  356. X                write('if (');
  357. X                increment;
  358. X                eexpr(tp^.tifxp);
  359. X                stusd := setused;
  360. X                setused := false;
  361. X                if tp^.tthen^.tt = nbegin then
  362. X                    begin
  363. X                    decrement;
  364. X                    write(') ');
  365. X                    estmt(tp^.tthen);
  366. X                    if tp^.telse <> nil then
  367. X                        write(space)
  368. X                    else
  369. X                        writeln
  370. X                    end
  371. X                else begin
  372. X                    writeln(')');
  373. X                    estmt(tp^.tthen);
  374. X                    decrement;
  375. X                    if tp^.telse <> nil then
  376. X                        indent
  377. X                     end;
  378. X                if tp^.telse <> nil then
  379. X                    begin
  380. X                    write('else');
  381. X                    if tp^.telse^.tt = nbegin then
  382. X                        begin
  383. X                        write(space);
  384. X                        estmt(tp^.telse);
  385. X                        writeln
  386. X                        end
  387. X                    else begin
  388. X                        increment;
  389. X                        writeln;
  390. X                        estmt(tp^.telse);
  391. X                        decrement
  392. X                         end;
  393. X                    end;
  394. X                setused := stusd or setused
  395. X                end;
  396. X              ncase:
  397. X                begin
  398. X                indent;
  399. X                write('switch (');
  400. X                increment;
  401. X                eexpr(tp^.tcasxp);
  402. X                writeln(') {');
  403. X                decrement;
  404. X                echoise(tp^.tcaslst);
  405. X                indent;
  406. X                writeln('  default:');
  407. X                increment;
  408. X                if tp^.tcasother = nil then
  409. X                    begin
  410. X                    indent;
  411. X                    writeln('Caseerror(Line);')
  412. X                    end
  413. X                else
  414. X                    estmt(tp^.tcasother);
  415. X                decrement;
  416. X                indent;
  417. X                writeln('}')
  418. X                end;
  419. X              nwith:
  420. X                begin
  421. X                indent;
  422. X                writeln('{');
  423. X                increment;
  424. X                tq := tp^.twithvar;
  425. X                while tq <> nil do
  426. X                    begin
  427. X                    indent;
  428. X                    write(registr);
  429. X                    ewithtype(tq^.texpw);
  430. X                    write(' *');
  431. X                    locid1 := mkvariable('W');
  432. X                    printid(locid1);
  433. X                    write(' = ');
  434. X                    eaddr(tq^.texpw);
  435. X                    writeln(';');
  436. X                    cenv(locid1, tq^.tenv);
  437. X                    tq := tq^.tnext
  438. X                    end;
  439. X                writeln;
  440. X                if tp^.twithstmt^.tt = nbegin then
  441. X                    estmt(tp^.twithstmt^.tbegin)
  442. X                else
  443. X                    estmt(tp^.twithstmt);
  444. X                decrement;
  445. X                indent;
  446. X                writeln('}')
  447. X                end;
  448. X              ngoto:
  449. X                begin
  450. X                indent;
  451. X                if islocal(tp^.tlabel) then
  452. X                    writeln('goto L',
  453. X                        tp^.tlabel^.tsym^.lno:1, ';')
  454. X                else begin
  455. X                    tq := idup(tp^.tlabel);
  456. X                    writeln('longjmp(J[',    (* LIB *)
  457. X                        tq^.tstat:1, '].jb, ',
  458. X                        tp^.tlabel^.tsym^.lno:1, ');')
  459. X                     end
  460. X                end;
  461. X              nlabstmt:
  462. X                begin
  463. X                decrement;
  464. X                indent;
  465. X                writeln('L', tp^.tlabno^.tsym^.lno:1, ':');
  466. X                increment;
  467. X                estmt(tp^.tstmt)
  468. X                end;
  469. X              nassign:
  470. X                begin
  471. X                indent;
  472. X                eexpr(tp);
  473. X                writeln(';')
  474. X                end;
  475. X              ncall:
  476. X                begin
  477. X                indent;
  478. X                tq := idup(tp^.tcall);
  479. X                if (tq^.tt in [nfunc, nproc]) and
  480. X                        (tq^.tsubstmt <> nil) then
  481. X                    if tq^.tsubstmt^.tt = npredef then
  482. X                        epredef(tq, tp)
  483. X                    else begin
  484. X                        ecall(tp);
  485. X                        writeln(';')
  486. X                         end
  487. X                else begin
  488. X                    ecall(tp);
  489. X                    writeln(';')
  490. X                     end
  491. X                end;
  492. X              npush:
  493. X                begin
  494. X                indent;
  495. X                eglobid(tp^.ttmp);
  496. X                write(' = ');
  497. X                eglobid(tp^.tglob);
  498. X                writeln(';');
  499. X                indent;
  500. X                eglobid(tp^.tglob);
  501. X                write(' = ');
  502. X                if tp^.tloc^.tt = nid then
  503. X                    begin
  504. X                    tq := idup(tp^.tloc);
  505. X                    if tq^.tt in [nparproc, nparfunc] then
  506. X                        printid(tp^.tloc^.tsym^.lid)
  507. X                    else
  508. X                        eaddr(tp^.tloc)
  509. X                    end
  510. X                else
  511. X                    eaddr(tp^.tloc);
  512. X                writeln(';')
  513. X                end;
  514. X              npop:
  515. X                begin
  516. X                indent;
  517. X                eglobid(tp^.tglob);
  518. X                write(' = ');
  519. X                eglobid(tp^.ttmp);
  520. X                writeln(';')
  521. X                end;
  522. X              nbreak:
  523. X                begin
  524. X                indent;
  525. X                write('if (');
  526. X                eexpr(tp^.tbrkid);
  527. X                write(' == ');
  528. X                eexpr(tp^.tbrkxp);
  529. X                writeln(') break;')
  530. X                end;
  531. X              nempty:
  532. X                if not (tp^.tup^.tt in [npgm, nproc, nfunc,
  533. X                        nchoise, nbegin, nrepeat]) then
  534. X                    begin
  535. X                    indent;
  536. X                    writeln(';')
  537. X                    end
  538. X            end;(* case *)
  539. X            if setused and
  540. X                (tp^.tup^.tt in [npgm, nproc, nfunc, nrepeat,
  541. X                        nbegin, nchoise, nwith]) then
  542. X                begin
  543. X                indent;
  544. X                writeln('Claimset();');
  545. X                setused := false
  546. X                end;
  547. X            tp := tp^.tnext
  548. X            end
  549. X    end;    (* estmt *)
  550. X
  551. X    (*    Emit initialization for non-local gotos.        *)
  552. X    procedure elabel(tp : treeptr);
  553. X
  554. X    var    tq    : treeptr;
  555. X        i    : integer;
  556. X
  557. X    begin
  558. X        i := 0;
  559. X        tq := tp^.tsublab;
  560. X        while tq <> nil do
  561. X            begin
  562. X            if tq^.tsym^.lgo then
  563. X                i := i + 1;
  564. X            tq := tq^.tnext
  565. X            end;
  566. X        if i =1 then
  567. X            begin
  568. X            tq := tp^.tsublab;
  569. X            while not tq^.tsym^.lgo do
  570. X                tq := tq^.tnext;
  571. X            indent;
  572. X            writeln('if (',
  573. X                'setjmp(J[', tp^.tstat:1, '].jb))'); (* LIB *)
  574. X            writeln(tab1, 'goto L', tq^.tsym^.lno:1, ';')
  575. X            end
  576. X        else if i > 1 then
  577. X            begin
  578. X            indent;
  579. X            writeln('switch (',
  580. X                'setjmp(J[', tp^.tstat:1, '].jb)) {'); (* LIB *)
  581. X            indent;
  582. X            writeln('  case 0:');
  583. X            indent;
  584. X            writeln(tab1, 'break');
  585. X            tq := tp^.tsublab;
  586. X            while tq <> nil do
  587. X                begin
  588. X                if tq^.tsym^.lgo then
  589. X                    begin
  590. X                    (* label used in non-local goto *)
  591. X                    indent;
  592. X                    writeln('  case ',
  593. X                            tq^.tsym^.lno:1, ':');
  594. X                    indent;
  595. X                    writeln(tab1, 'goto L',
  596. X                            tq^.tsym^.lno:1, ';')
  597. X                    end;
  598. X                tq := tq^.tnext
  599. X                end;
  600. X            indent;
  601. X            writeln('  default:');
  602. X            indent;
  603. X            writeln(tab1, 'Caseerror(Line)');
  604. X            indent;
  605. X            writeln('}')
  606. X            end
  607. X    end;    (* elabel *)
  608. X
  609. X    (*    Emit declaration for lower bound of conformant array.    *)
  610. X    procedure econf(tp : treeptr);
  611. X
  612. X    var    tq    : treeptr;
  613. X
  614. X    begin
  615. X        while tp <> nil do
  616. X            begin
  617. X            if tp^.tt = nvarpar then
  618. X                if tp^.tbind^.tt = nconfarr then
  619. X                    begin
  620. X                    indent;
  621. X                    etypedef(tp^.tbind^.tindtyp);
  622. X                    write(tab1);
  623. X                    tq := tp^.tbind^.tcindx^.tlo;
  624. X                    printid(tq^.tsym^.lid);
  625. X                    write(' = (');
  626. X                    etypedef(tp^.tbind^.tindtyp);
  627. X                    writeln(')0;')
  628. X                    end;
  629. X            tp := tp^.tnext
  630. X            end
  631. X    end;    (* econf *)
  632. X
  633. X    (*    Emit code for subroutines.                *)
  634. X    procedure esubr(tp : treeptr);
  635. X
  636. X    label    999;
  637. X
  638. X    var    tq, ti    : treeptr;
  639. X
  640. X    begin
  641. X        while tp <> nil do
  642. X            begin
  643. X            (* emit nested subroutines *)
  644. X            if tp^.tsubsub <> nil then
  645. X                begin
  646. X                (* emit forward declaration of this subroutine
  647. X                   in case of recursion *)
  648. X                etypedef(tp^.tfuntyp);
  649. X                write(space);
  650. X                printid(tp^.tsubid^.tsym^.lid);
  651. X                writeln('();');
  652. X                writeln;
  653. X                esubr(tp^.tsubsub)
  654. X                end;
  655. X            (* emit this subroutine *)
  656. X            if tp^.tsubstmt = nil then
  657. X                begin
  658. X                (* forward/external decl *)
  659. X                if tp^.tsubid^.tsym^.lsymdecl^.tup = tp then
  660. X                    write(xtern);
  661. X                etypedef(tp^.tfuntyp);
  662. X                write(space);
  663. X                printid(tp^.tsubid^.tsym^.lid);
  664. X                writeln('();');
  665. X                goto 999
  666. X                end;
  667. X            write(space);
  668. X            etypedef(tp^.tfuntyp);
  669. X            writeln;
  670. X            printid(tp^.tsubid^.tsym^.lid);
  671. X            write('(');
  672. X            tq := tp^.tsubpar;
  673. X            while tq <> nil do
  674. X                begin
  675. X                case tq^.tt of
  676. X                  nvarpar,
  677. X                  nvalpar:
  678. X                    begin
  679. X                    ti := tq^.tidl;
  680. X                    while ti <> nil do
  681. X                        begin
  682. X                        printid(ti^.tsym^.lid);
  683. X                        ti := ti^.tnext;
  684. X                        if ti <> nil then
  685. X                            write(', ');
  686. X                        end;
  687. X                    if tq^.tbind^.tt = nconfarr then
  688. X                        begin
  689. X                        (* add upper bound parameter *)
  690. X                        ti := tq^.tbind^.tcindx^.thi;
  691. X                        write(', ');
  692. X                        printid(ti^.tsym^.lid)
  693. X                        end;
  694. X                    end;
  695. X                  nparproc,
  696. X                  nparfunc:
  697. X                    begin
  698. X                    ti := tq^.tparid;
  699. X                    printid(ti^.tsym^.lid)
  700. X                    end
  701. X                end;(* case *)
  702. X                tq := tq^.tnext;
  703. X                if tq <> nil then
  704. X                    write(', ');
  705. X                end;
  706. X            writeln(')');
  707. X            increment;
  708. X            evar(tp^.tsubpar);
  709. X            writeln('{');
  710. X            econf(tp^.tsubpar);
  711. X            econst(tp^.tsubconst);
  712. X            etype(tp^.tsubtype);
  713. X            evar(tp^.tsubvar);
  714. X
  715. X            if (tp^.tsubconst <> nil) or (tp^.tsubtype <> nil) or
  716. X                    (tp^.tsubvar <> nil) then
  717. X                writeln;
  718. X            elabel(tp);
  719. X            estmt(tp^.tsubstmt);
  720. X            if tp^.tt = nfunc then
  721. X                begin
  722. X                (* return value in the FIRST variable,
  723. X                   see renamf() above *)
  724. X                indent;
  725. X                write('return ');
  726. X                printid(tp^.tsubvar^.tidl^.tsym^.lid);
  727. X                writeln(';');
  728. X                end;
  729. X            decrement;
  730. X            writeln('}');
  731. X        999:
  732. X            writeln;
  733. X            tp := tp^.tnext
  734. X            end
  735. X    end;    (* esubr *)
  736. X
  737. X    function use(d : predefs) : boolean;
  738. X
  739. X    begin
  740. X        use := defnams[d]^.lused
  741. X    end;
  742. X
  743. X    (*    Emit code for main program.                *)
  744. X    procedure eprogram(tp : treeptr);
  745. X
  746. X        (*    Symbol that sp refers to is renamed if it has    *)
  747. X        (*    been redefined in source program.        *)
  748. X        procedure capital(sp : symptr);
  749. X
  750. X        var    tb    : toknbuf;
  751. X
  752. X        begin
  753. X            if sp^.lid^.inref > 1 then
  754. X                begin
  755. X                gettokn(sp^.lid^.istr, tb);
  756. X                tb[1] := uppercase(tb[1]);
  757. X                sp^.lid := saveid(tb)
  758. X                end
  759. X        end;
  760. X
  761. X        procedure etextdef;
  762. X
  763. X        var    tq    : treeptr;
  764. X
  765. X        begin
  766. X            write('typedef ');
  767. X            tq := mknode(nfileof);
  768. X            tq^.tof := typnods[tchar];
  769. X            etypedef(tq);
  770. X            writeln(tab1, 'text;')
  771. X        end;
  772. X
  773. X    begin    (* eprogram *)
  774. X        if tp^.tsubid <> nil then
  775. X            begin
  776. X            (* program heading was seen *)
  777. X            writeln('/', '*');
  778. X            write('**    Code derived from program ');
  779. X            printid(tp^.tsubid^.tsym^.lid);
  780. X            writeln;
  781. X            writeln('*', '/');
  782. X            writeln(xtern, voidtyp, tab1, 'exit();')
  783. X            end;
  784. X        if usecase or usesets or
  785. X           use(dinput) or use(doutput) or
  786. X           use(dwrite) or use(dwriteln) or use(dmessage) or
  787. X           use(deof) or use(deoln) or use(dflush) or use(dpage) or
  788. X           use(dread) or use(dreadln) or use(dclose) or
  789. X           use(dreset) or use(drewrite) or use(dget) or use(dput) then
  790. X            begin
  791. X            writeln('/', '*');
  792. X            writeln('**    Definitions for i/o');
  793. X            writeln('*', '/');
  794. X            writeln(include, '<stdio.h>')    (* LIB *)
  795. X            end;
  796. X        if use(dinput) or use(doutput) or use(dtext) then
  797. X            begin
  798. X            etextdef;
  799. X            if use(dinput) then
  800. X                begin
  801. X                if tp^.tsubid = nil then
  802. X                    write(xtern);
  803. X                write('text', tab1);
  804. X                printid(defnams[dinput]^.lid);
  805. X                if tp^.tsubid <> nil then
  806. X                    write(' = { stdin, 0, 0 }');
  807. X                writeln(';')
  808. X                end;
  809. X            if use(doutput) then
  810. X                begin
  811. X                if tp^.tsubid = nil then
  812. X                    write(xtern);
  813. X                write('text', tab1);
  814. X                printid(defnams[doutput]^.lid);
  815. X                if tp^.tsubid <> nil then
  816. X                    write(' = { stdout, 0, 0 }');
  817. X                writeln(';')
  818. X                end
  819. X            end;
  820. X        if use(dinput) or use(dget) or use(dread) or use(dreadln) or
  821. X           use(deof) or use(deoln) or use(dreset) or use(drewrite) then
  822. X            begin
  823. X            writeln(define, 'Fread(x, f) ',
  824. X                'fread((char *)&x, sizeof(x), 1, f)'); (* LIB *)
  825. X            writeln(define, 'Get(f) Fread((f).buf, (f).fp)');
  826. X            writeln(define, 'Getx(f) (f).init = 1, ',
  827. X                '(f).eoln = (((f).buf = ',
  828. X                    'fgetc((f).fp)',    (* LIB *)
  829. X                    ') == ', nlchr, ') ? (((f).buf = ',
  830. X                        spchr, '), 1) : 0');
  831. X            writeln(define, 'Getchr(f) (f).buf, Getx(f)')
  832. X            end;
  833. X        if use(dread) or use(dreadln) then
  834. X            begin
  835. X            writeln(static, 'FILE', tab1, '*Tmpfil;');
  836. X            writeln(static, 'long', tab1, 'Tmplng;');
  837. X            writeln(static, 'double', tab1, 'Tmpdbl;');
  838. X            writeln(define, 'Fscan(f) (f).init ? ',
  839. X                'ungetc((f).buf, (f).fp)',    (* LIB *)
  840. X                    ' : 0, Tmpfil = (f).fp');
  841. X            writeln(define, 'Scan(p, a) ',
  842. X                'Scanck(fscanf(Tmpfil, p, a))'); (* LIB *)
  843. X            writeln(voidtyp, tab1, 'Scanck();');
  844. X            if use(dreadln) then
  845. X                writeln(voidtyp, tab1, 'Getl();');
  846. X            end;
  847. X        if use(deoln) then
  848. X            writeln(define, 'Eoln(f) ((f).eoln ? true : false)');
  849. X        if use(deof) then
  850. X            writeln(define, 'Eof(f) ',
  851. X                '((((f).init == 0) ? (Get(f)) : 0, ',
  852. X                    '((f).eof ? 1 : ',
  853. X                        'feof((f).fp))) ? ', (* LIB *)
  854. X                            'true : false)');
  855. X        if use(doutput) or use(dput) or
  856. X                use(dwrite) or use(dwriteln) or
  857. X                use(dreset) or use(drewrite) or use(dclose) then
  858. X            begin
  859. X            writeln(define, 'Fwrite(x, f) ',
  860. X                'fwrite((char *)&x, sizeof(x), 1, f)');(* LIB *)
  861. X            writeln(define, 'Put(f) Fwrite((f).buf, (f).fp)');
  862. X            writeln(define, 'Putx(f) (f).eoln = ((f).buf == ',
  863. X                nlchr, '), ', voidcast,
  864. X                'fputc((f).buf, (f).fp)'); (* LIB *)
  865. X            writeln(define, 'Putchr(c, f) (f).buf = (c), Putx(f)');
  866. X            writeln(define, 'Putl(f, v) (f).eoln = v')
  867. X            end;
  868. X        if use(dreset) or use(drewrite) or use(dclose) then
  869. X            writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ',
  870. X                '(Putchr(', nlchr, ', f), 0) : 0, ',
  871. X                    'rewind((f).fp)');    (* LIB *)
  872. X        if use(dclose) then
  873. X            begin
  874. X            writeln(define, 'Close(f) (f).init = ',
  875. X                '((f).init ? (',
  876. X                    'fclose((f).fp), ',    (* LIB *)
  877. X                        '0) : 0), (f).fp = NULL');
  878. X            writeln(define, 'Closex(f) (f).init = ',
  879. X                '((f).init ? ',
  880. X                    '(Finish(f), ',
  881. X                    'fclose((f).fp), ',    (* LIB *)
  882. X                        '0) : 0), (f).fp = NULL')
  883. X            end;
  884. X        if use(dreset) then
  885. X            begin
  886. X            writeln(ifdef, 'READONLY');
  887. X            writeln(static, chartyp, tab1, 'Rmode[] = "r";');
  888. X            writeln(elsif);
  889. X            writeln(static, chartyp, tab1, 'Rmode[] = "r+";');
  890. X            writeln(endif);
  891. X            writeln(define, 'Reset(f, n) (f).init = ',
  892. X                '(f).init ? rewind((f).fp) : ',    (* LIB *)
  893. X                '(((f).fp = Fopen(n, Rmode)), 1), ',
  894. X                    '(f).eof = (f).out = 0, Get(f)');
  895. X            writeln(define, 'Resetx(f, n) (f).init = ',
  896. X                '(f).init ? (Finish(f)) : ',
  897. X                '(((f).fp = Fopen(n, Rmode)), 1), ',
  898. X                    '(f).eof = (f).out = 0, Getx(f)');
  899. X            usefopn := true
  900. X            end;
  901. X        if use(drewrite) then
  902. X            begin
  903. X            writeln(ifdef, 'WRITEONLY');
  904. X            writeln(static, chartyp, tab1, 'Wmode[] = "w";');
  905. X            writeln(elsif);
  906. X            writeln(static, chartyp, tab1, 'Wmode[] = "w+";');
  907. X            writeln(endif);
  908. X            writeln(define, 'Rewrite(f, n) (f).init = ',
  909. X                '(f).init ? rewind((f).fp) : ',    (* LIB *)
  910. X                '(((f).fp = Fopen(n, Wmode)), 1), ',
  911. X                    '(f).out = (f).eof = 1');
  912. X            writeln(define, 'Rewritex(f, n) (f).init = ',
  913. X                '(f).init ? (Finish(f)) : ',
  914. X                '(((f).fp = Fopen(n, Wmode)), 1), ',
  915. X                    '(f).out = (f).eof = (f).eoln = 1');
  916. X            usefopn := true
  917. X            end;
  918. X        if usefopn then
  919. X            begin
  920. X            writeln('FILE    *Fopen();');
  921. X            writeln(define, 'MAXFILENAME 256')
  922. X            end;
  923. X        if usecase or usejmps then
  924. X            begin
  925. X            writeln('/', '*');
  926. X            writeln('**    Definitions for case-statements');
  927. X            writeln('**    and for non-local gotos');
  928. X            writeln('*', '/');
  929. X            writeln(define, 'Line __LINE__');
  930. X            writeln(voidtyp, tab1, 'Caseerror();')
  931. X            end;
  932. X        if usejmps then
  933. X            begin
  934. X            writeln(include, '<setjmp.h>');    (* LIB *)
  935. X            writeln(static, 'struct Jb { jmp_buf', tab1, 'jb; } J[',
  936. X                            (maxlevel+1):1, '];')
  937. X            end;
  938. X        if use(dinteger) or use(dmaxint) or 
  939. X            use(dboolean) or use(dfalse) or use(dtrue) or
  940. X                use(deof) or use(deoln) or use(dexp) or
  941. X                use(dln) or use(dsqr) or use(dsin) or
  942. X                use(dcos) or use(dtan) or use(darctan) or
  943. X                use(dsqrt) or use(dreal) then
  944. X            begin
  945. X            writeln('/', '*');
  946. X            writeln('**    Definitions for standard types');
  947. X            writeln('*', '/')
  948. X            end;
  949. X        if usecomp then
  950. X            begin
  951. X            writeln(xtern, inttyp, ' strncmp();');    (* LIB *)
  952. X            writeln(define,
  953. X                'Cmpstr(x, y) ',
  954. X                'strncmp((x), (y), sizeof(x))')    (* LIB *)
  955. X            end;
  956. X        if use(dboolean) or use(dfalse) or use(dtrue) or
  957. X            use(deof) or use(deoln) or usesets then
  958. X            begin
  959. X            capital(defnams[dboolean]);
  960. X            write(typdef, chartyp, tab1);
  961. X            printid(defnams[dboolean]^.lid);
  962. X            writeln(';');
  963. X            capital(defnams[dfalse]);
  964. X            write(define);
  965. X            printid(defnams[dfalse]^.lid);
  966. X            write(' (');
  967. X            printid(defnams[dboolean]^.lid);
  968. X            writeln(')0');
  969. X            capital(defnams[dtrue]);
  970. X            write(define);
  971. X            printid(defnams[dtrue]^.lid);
  972. X            write(' (');
  973. X            printid(defnams[dboolean]^.lid);
  974. X            writeln(')1');
  975. X            writeln(xtern, chartyp, tab1, '*Bools[];')
  976. X            end;
  977. X        capital(defnams[dinteger]);
  978. X        if use(dinteger) then
  979. X            begin
  980. X            write(typdef, inttyp, tab1);
  981. X            printid(defnams[dinteger]^.lid);
  982. X            writeln(';')
  983. X            end;
  984. X        if use(dmaxint) then
  985. X            writeln(define, 'maxint', tab1, maxint:1);
  986. X        capital(defnams[dreal]);
  987. X        if use(dreal) then
  988. X            begin
  989. X            write(typdef, realtyp, tab1);
  990. X            printid(defnams[dreal]^.lid);
  991. X            writeln(';')
  992. X            end;
  993. X        if use(dexp) then
  994. X            writeln(xtern, doubletyp, ' exp();');    (* LIB *)
  995. X        if use(dln) then
  996. X            writeln(xtern, doubletyp, ' log();');    (* LIB *)
  997. X        if use(dsqr) then
  998. X            writeln(xtern, doubletyp, ' pow();');    (* LIB *)
  999. X        if use(dsin) then
  1000. X            writeln(xtern, doubletyp, ' sin();');    (* LIB *)
  1001. X        if use(dcos) then
  1002. X            writeln(xtern, doubletyp, ' cos();');    (* LIB *)
  1003. X        if use(dtan) then
  1004. X            writeln(xtern, doubletyp, ' tan();');    (* LIB *)
  1005. X        if use(darctan) then
  1006. X            writeln(xtern, doubletyp, ' atan();');    (* LIB *)
  1007. X        if use(dsqrt) then
  1008. X            writeln(xtern, doubletyp, ' sqrt();');    (* LIB *)
  1009. X        if use(dabs) and use(dreal) then
  1010. X            writeln(xtern, doubletyp, ' fabs();');    (* LIB *)
  1011. X        if use(dhalt) then
  1012. X            writeln(xtern, voidtyp, ' abort();');    (* LIB *)
  1013. X        if use(dnew) or usenilp then
  1014. X            begin
  1015. X            writeln('/', '*');
  1016. X            writeln('**    Definitions for pointers');
  1017. X            writeln('*', '/');
  1018. X            end;
  1019. X        if use(dnew) then
  1020. X            begin
  1021. X            writeln(ifndef, 'Unionoffs');
  1022. X            writeln(define, 'Unionoffs(p, m) ',
  1023. X                '(((long)(&(p)->m))-((long)(p)))');    (* CPU *)
  1024. X            writeln(endif)
  1025. X            end;
  1026. X        if usenilp then
  1027. X            writeln(define, 'NIL 0');        (* CPU *)
  1028. X        if use(dnew) then
  1029. X            writeln(xtern, chartyp, ' *malloc();');    (* LIB *)
  1030. X        if use(ddispose) then
  1031. X            writeln(xtern, voidtyp, ' free();');    (* LIB *)
  1032. X        if usesets then
  1033. X            begin
  1034. X            writeln('/', '*');
  1035. X            writeln('**    Definitions for set-operations');
  1036. X            writeln('*', '/');
  1037. X            writeln(define, 'Claimset() ',
  1038. X                voidcast, 'Currset(0, (', setptyp, ')0)');
  1039. X            writeln(define, 'Newset() ',
  1040. X                    'Currset(1, (', setptyp, ')0)');
  1041. X            writeln(define, 'Saveset(s) Currset(2, s)');
  1042. X            writeln(define, 'setbits ', setbits:1);
  1043. X            writeln(typdef, wordtype, tab1, setwtyp, ';');
  1044. X            writeln(typdef, setwtyp, ' *', tab1, setptyp, ';');
  1045. X            printid(defnams[dboolean]^.lid);
  1046. X            writeln(tab1, 'Member(), Le(), Ge(), Eq(), Ne();');
  1047. X            writeln(setptyp, tab1, 'Union(), Diff();');
  1048. X            writeln(setptyp, tab1, 'Insmem(), Mksubr();');
  1049. X            writeln(setptyp, tab1, 'Currset(), Inter();');
  1050. X            writeln(static, setptyp, tab1, 'Tmpset;');
  1051. X            writeln(xtern, setptyp, tab1, 'Conset[];');
  1052. X            writeln(voidtyp, tab1, 'Setncpy();')
  1053. X            end;
  1054. X        writeln(xtern, chartyp, ' *strncpy();');    (* LIB *)
  1055. X        if use(dargc) or use(dargv) then
  1056. X            begin
  1057. X            writeln('/', '*');
  1058. X            writeln('**    Definitions for argv-operations');
  1059. X            writeln('*', '/');
  1060. X            writeln(inttyp, tab1, 'argc;');        (* OS *)
  1061. X            writeln(chartyp, tab1, '**argv;');
  1062. X            writeln(' void');
  1063. X            writeln('Argvgt(n, cp, l)');
  1064. X            writeln(inttyp, tab1, 'n;');
  1065. X            writeln(registr, inttyp, tab1, 'l;');
  1066. X            writeln(registr, chartyp, tab1, '*cp;');
  1067. X            writeln('{');
  1068. X            writeln(tab1, registr, chartyp, tab1, '*sp;');
  1069. X            writeln;
  1070. X            writeln(tab1, 'for (sp = argv[n]; l > 0 && *sp; l--)');
  1071. X            writeln(tab2, '*cp++ = *sp++;');
  1072. X            writeln(tab1, 'while (l-- > 0)');
  1073. X            writeln(tab2, '*cp++ = ', spchr, ';');
  1074. X            writeln('}');
  1075. X            end;
  1076. X        if (tp^.tsubconst <> nil) or (tp^.tsubtype<> nil) or
  1077. X            (tp^.tsubvar <> nil) or (tp^.tsubsub <> nil) then
  1078. X            begin
  1079. X            writeln('/', '*');
  1080. X            writeln('**    Start of program definitions');
  1081. X            writeln('*', '/');
  1082. X            end;
  1083. X        econst(tp^.tsubconst);
  1084. X        etype(tp^.tsubtype);
  1085. X        evar(tp^.tsubvar);
  1086. X        if tp^.tsubsub <> nil then
  1087. X            writeln;
  1088. X        esubr(tp^.tsubsub);
  1089. X        if tp^.tsubid <> nil then
  1090. X            begin
  1091. X            (* program heading was seen *)
  1092. X            writeln('/', '*');
  1093. X            writeln('**    Start of program code');
  1094. X            writeln('*', '/');
  1095. X            if use(dargc) or use(dargv) then
  1096. X                begin
  1097. X                writeln('main(_ac, _av)');    (* OS *)
  1098. X                writeln(inttyp, tab1, '_ac;');
  1099. X                writeln(chartyp, tab1, '*_av[];');
  1100. X                writeln('{');
  1101. X                writeln;
  1102. X                writeln(tab1, 'argc = _ac;');
  1103. X                writeln(tab1, 'argv = _av;')
  1104. X                end
  1105. X            else begin
  1106. X                writeln('main()');
  1107. X                writeln('{')
  1108. X                 end;
  1109. X            increment;
  1110. X            elabel(tp);
  1111. X            estmt(tp^.tsubstmt);
  1112. X            indent;
  1113. X            writeln('exit(0);');
  1114. X            decrement;
  1115. X            writeln('}');
  1116. X            writeln('/', '*');
  1117. X            writeln('**    End of program code');
  1118. X            writeln('*', '/')
  1119. X            end
  1120. X    end;    (* eprogram *)
  1121. X
  1122. X    (*    Emit definitions for constant sets    *)
  1123. X    procedure econset(tp : treeptr; len : integer);
  1124. X
  1125. X    var    i    : integer;
  1126. X
  1127. X        function size(tp : treeptr) : integer;
  1128. X
  1129. X        var    r, x    : integer;
  1130. X
  1131. X        begin
  1132. X            r := 0;
  1133. X            while tp <> nil do
  1134. X                begin
  1135. X                if tp^.tt = nrange then
  1136. X                    x := cvalof(tp^.texpr)
  1137. X                else if tp^.tt = nempty then
  1138. X                    x := 0
  1139. X                else
  1140. X                    x := cvalof(tp);
  1141. X                if x > r then
  1142. X                    r := x;
  1143. X                tp := tp^.tnext
  1144. X                end;
  1145. X            size := csetwords(r+1)
  1146. X        end;
  1147. X
  1148. X        (*    Emit bits in a constant set    *)
  1149. X        procedure ebits(tp : treeptr);
  1150. X
  1151. X        type    bitset    = set of 0 .. setbits;
  1152. X
  1153. X        var    sets    : array [ 0 .. maxsetrange ] of bitset;
  1154. X            s, m, n    : integer;
  1155. X
  1156. X            procedure eword(s : bitset);
  1157. X
  1158. X            const    bitshex    = 4;    (* nr of bits in a hex-digit *)
  1159. X
  1160. X            var    n, i    : integer;
  1161. X                x    : 0 .. setbits;
  1162. X
  1163. X            begin
  1164. X                n := 0;
  1165. X                while n <= setbits do
  1166. X                    n := n + bitshex;
  1167. X                n := n - bitshex;
  1168. X                while n >= 0 do
  1169. X                    begin
  1170. X                    (* compute 1 hexdigit *)
  1171. X                    x := 0;
  1172. X                    for i := 0 to bitshex - 1 do
  1173. X                        if (n + i) in s then
  1174. X                            case i of
  1175. X                              0:    x := x + 1;
  1176. X                              1:    x := x + 2;
  1177. X                              2:    x := x + 4;
  1178. X                              3:    x := x + 8
  1179. X                            end;(* case *)
  1180. X                    (* print it *)
  1181. X                    write(hexdig[x]);
  1182. X                    n := n - bitshex
  1183. X                    end
  1184. X            end;
  1185. X
  1186. X        begin
  1187. X            s := size(tp);
  1188. X            for n := 0 to s - 1 do
  1189. X                sets[n] := [];
  1190. X            while tp <> nil do
  1191. X                begin
  1192. X                if tp^.tt = nrange then
  1193. X                    for m := cvalof(tp^.texpl) to
  1194. X                            cvalof(tp^.texpr) do
  1195. X                        begin
  1196. X                        n := m div (setbits+1);
  1197. X                        sets[n] := sets[n] +
  1198. X                            [m mod (setbits+1)]
  1199. X                        end
  1200. X                else if tp^.tt <> nempty then
  1201. X                    begin
  1202. X                    m := cvalof(tp);
  1203. X                    n := m div (setbits+1);
  1204. X                    sets[n] := sets[n] +
  1205. X                        [m mod (setbits+1)]
  1206. X                    end;
  1207. X                tp := tp^.tnext
  1208. X                end;
  1209. X            write(tab1, s:1);
  1210. X            for n := 0 to s - 1 do
  1211. X                begin
  1212. X                write(',');
  1213. X                if n mod 6 = 0 then
  1214. X                    writeln;
  1215. X                write(tab1, '0x');
  1216. X                eword(sets[n]);
  1217. X                end;
  1218. X            writeln
  1219. X        end;
  1220. X
  1221. X    begin
  1222. X        i := 0;
  1223. X        while tp <> nil do
  1224. X            begin
  1225. X            writeln(static, setwtyp, tab1, 'Q', i:1, '[] = {');
  1226. X            ebits(tp^.texps);
  1227. X            writeln('};');
  1228. X            i := i + 1;
  1229. X            tp := tp^.tnext
  1230. X            end;
  1231. X        writeln(static, setwtyp, tab1, '*Conset[] = {');
  1232. X        for i := len - 1 downto 1 do
  1233. X            begin
  1234. X            write(tab1, 'Q', i:1, ',');
  1235. X            if i mod 6 = 5 then
  1236. X                writeln
  1237. X            end;
  1238. X        writeln(tab1, 'Q0');
  1239. X        writeln('};');
  1240. X    end;
  1241. X
  1242. Xbegin    (* emit *)
  1243. X    indnt := 0;
  1244. X    varno := 0;
  1245. X    conflag := false;
  1246. X    setused := false;
  1247. X    dropset := false;
  1248. X    doarrow := 0;
  1249. X    eprogram(top);
  1250. X    if usebool then
  1251. X        writeln(chartyp, tab1, '*Bools[] = { "false", "true" };');
  1252. X    if usescan then
  1253. X        begin
  1254. X        writeln;
  1255. X        writeln(static, voidtyp);
  1256. X        writeln('Scanck(n)');
  1257. X        writeln(inttyp, tab1, 'n;');
  1258. X        writeln('{');
  1259. X        writeln(tab1, 'if (n != 1) {');
  1260. X        writeln(tab2, voidcast, 'fprintf(stderr, "Bad input\n");');
  1261. X        writeln(tab2, 'exit(1);');
  1262. X        writeln(tab1, '}');
  1263. X        writeln('}')
  1264. X        end;
  1265. X    if usegetl then
  1266. X        begin
  1267. X        writeln;
  1268. X        writeln(static, voidtyp);
  1269. X        writeln('Getl(f)');
  1270. X        writeln(' text', tab1, '*f;');
  1271. X        writeln('{');
  1272. X        writeln(tab1, 'while (f->eoln == 0)');
  1273. X        writeln(tab2, 'Getx(*f);');
  1274. X        writeln(tab1, 'Getx(*f);');
  1275. X        writeln('}')
  1276. X        end;
  1277. X    if usefopn then
  1278. X        begin
  1279. X        writeln;
  1280. X        writeln(static, 'FILE *');
  1281. X        writeln('Fopen(n, m)');
  1282. X        writeln(chartyp, tab1, '*n, *m;');
  1283. X        writeln('{');
  1284. X        writeln(tab1, 'FILE', tab2, '*f;');
  1285. X        writeln(tab1, registr, chartyp, tab1, '*s;');
  1286. X        writeln(tab1, static, chartyp, tab1, 'ch = ',
  1287. X                        quote, 'A', quote, ';');
  1288. X        writeln(tab1, static, chartyp, tab1, 'tmp[MAXFILENAME];');
  1289. X        writeln(tab1, xtern , inttyp, tab1, 'unlink();'); (* OS *)
  1290. X        writeln;
  1291. X        writeln(tab1, 'if (n == NULL)');
  1292. X        writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);');
  1293. X        writeln(tab1, 'else {');
  1294. X        writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));');
  1295. X        writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ',
  1296. X            spchr, ' || *s == ', nulchr, '; )');
  1297. X        writeln(tab3, '*s-- = ', nulchr, ';');
  1298. X        writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {');
  1299. X        writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ',
  1300. X            quote, '%s', quote, '\n", n);');
  1301. X        writeln(tab3, 'exit(1);');
  1302. X        writeln(tab2, '}');
  1303. X        writeln(tab1, '}');
  1304. X        writeln(tab1, 's = tmp;');
  1305. X        writeln(tab1, 'if ((f = fopen(s, m)) == NULL) {');
  1306. X        writeln(tab2, voidcast,
  1307. X                'fprintf(stderr, "Cannot open: %s\n", s);');
  1308. X        writeln(tab2, 'exit(1);');
  1309. X        writeln(tab1, '}');
  1310. X        writeln(tab1, 'if (n == NULL)');
  1311. X        writeln(tab2, 'unlink(tmp);');    (* OS *)
  1312. X        writeln(tab1, 'return (f);');
  1313. X        writeln('}');
  1314. X        writeln(xtern, inttyp, tab1, 'rewind();')
  1315. X        end;
  1316. X    if setcnt > 0 then
  1317. X        econset(setlst, setcnt);
  1318. X    if useunion then
  1319. X        begin
  1320. X        writeln;
  1321. X        writeln(static, setptyp);
  1322. X        writeln('Union(p1, p2)');
  1323. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1324. X        writeln('{');
  1325. X        writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1326. X        writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1327. X        writeln(tab4, 'p3 = sp;');
  1328. X        writeln;
  1329. X        writeln(tab1, 'j = *p1;');
  1330. X        writeln(tab1, '*p3 = j;');
  1331. X        writeln(tab1, 'if (j > *p2)');
  1332. X        writeln(tab2, 'j = *p2;');
  1333. X        writeln(tab1, 'else');
  1334. X        writeln(tab2, '*p3 = *p2;');
  1335. X        writeln(tab1, 'k = *p1 - *p2;');
  1336. X        writeln(tab1, 'p1++, p2++, p3++;');
  1337. X        writeln(tab1, 'for (i = 0; i < j; i++)');
  1338. X        writeln(tab2, '*p3++ = (*p1++ | *p2++);');
  1339. X        writeln(tab1, 'while (k > 0) {');
  1340. X        writeln(tab2, '*p3++ = *p1++;');
  1341. X        writeln(tab2, 'k--;');
  1342. X        writeln(tab1, '}');
  1343. X        writeln(tab1, 'while (k < 0) {');
  1344. X        writeln(tab2, '*p3++ = *p2++;');
  1345. X        writeln(tab2, 'k++;');
  1346. X        writeln(tab1, '}');
  1347. X        writeln(tab1, 'return (Saveset(sp));');
  1348. X        writeln('}')
  1349. X        end;
  1350. X    if usediff then
  1351. X        begin
  1352. X        writeln;
  1353. X        writeln(static, setptyp);
  1354. X        writeln('Diff(p1, p2)');
  1355. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1356. X        writeln('{');
  1357. X        writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1358. X        writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1359. X        writeln(tab4, 'p3 = sp;');
  1360. X        writeln;
  1361. X        writeln(tab1, 'j = *p1;');
  1362. X        writeln(tab1, '*p3 = j;');
  1363. X        writeln(tab1, 'if (j > *p2)');
  1364. X        writeln(tab2, 'j = *p2;');
  1365. X        writeln(tab1, 'k = *p1 - *p2;');
  1366. X        writeln(tab1, 'p1++, p2++, p3++;');
  1367. X        writeln(tab1, 'for (i = 0; i < j; i++)');
  1368. X        writeln(tab2, '*p3++ = (*p1++ & ~ (*p2++));');
  1369. X        writeln(tab1, 'while (k > 0) {');
  1370. X        writeln(tab2, '*p3++ = *p1++;');
  1371. X        writeln(tab2, 'k--;');
  1372. X        writeln(tab1, '}');
  1373. X        writeln(tab1, 'return (Saveset(sp));');
  1374. X        writeln('}')
  1375. X        end;
  1376. X    if useintr then
  1377. X        begin
  1378. X        writeln;
  1379. X        writeln(static, setptyp);
  1380. X        writeln('Inter(p1, p2)');
  1381. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1382. X        writeln('{');
  1383. X        writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1384. X        writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1385. X        writeln(tab4, 'p3 = sp;');
  1386. X        writeln;
  1387. X        writeln(tab1, 'if ((j = *p1) > *p2)');
  1388. X        writeln(tab2, 'j = *p2;');
  1389. X        writeln(tab1, '*p3 = j;');
  1390. X        writeln(tab1, 'p1++, p2++, p3++;');
  1391. X        writeln(tab1, 'for (i = 0; i < j; i++)');
  1392. X        writeln(tab2, '*p3++ = (*p1++ & *p2++);');
  1393. X        writeln(tab1, 'return (Saveset(sp));');
  1394. X        writeln('}')
  1395. X        end;
  1396. X    if usememb then
  1397. X        begin
  1398. X        writeln;
  1399. X        write(static);
  1400. X        printid(defnams[dboolean]^.lid);
  1401. X        writeln;
  1402. X        writeln('Member(m, sp)');
  1403. X        writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1404. X        writeln(tab1, registr, setptyp, tab1, 'sp;');
  1405. X        writeln('{');
  1406. X        writeln(tab1, registr, usigned, inttyp,
  1407. X                    tab1, 'i = m / (setbits+1) + 1;');
  1408. X        writeln;
  1409. X        writeln(tab1, 'if ((i <= *sp) &&',
  1410. X                    ' (sp[i] & (1 << (m % (setbits+1)))))');
  1411. X        write(tab2, 'return (');
  1412. X        printid(defnams[dtrue]^.lid);
  1413. X        writeln(');');
  1414. X        write(tab1, 'return (');
  1415. X        printid(defnams[dfalse]^.lid);
  1416. X        writeln(');');
  1417. X        writeln('}')
  1418. X        end;
  1419. X    if useseq or usesne then
  1420. X        begin
  1421. X        writeln;
  1422. X        write(static);
  1423. X        printid(defnams[dboolean]^.lid);
  1424. X        writeln;
  1425. X        writeln('Eq(p1, p2)');
  1426. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1427. X        writeln('{');
  1428. X        writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1429. X        writeln;
  1430. X        writeln(tab1, 'i = *p1++;');
  1431. X        writeln(tab1, 'j = *p2++;');
  1432. X        writeln(tab1, 'while (i != 0 && j != 0) {');
  1433. X        writeln(tab2, 'if (*p1++ != *p2++)');
  1434. X        write(tab3, 'return (');
  1435. X        printid(defnams[dfalse]^.lid);
  1436. X        writeln(');');
  1437. X        writeln(tab2, 'i--, j--;');
  1438. X        writeln(tab1, '}');
  1439. X        writeln(tab1, 'while (i != 0) {');
  1440. X        writeln(tab2, 'if (*p1++ != 0)');
  1441. X        write(tab3, 'return (');
  1442. X        printid(defnams[dfalse]^.lid);
  1443. X        writeln(');');
  1444. X        writeln(tab2, 'i--;');
  1445. X        writeln(tab1, '}');
  1446. X        writeln(tab1, 'while (j != 0) {');
  1447. X        writeln(tab2, 'if (*p2++ != 0)');
  1448. X        write(tab3, 'return (');
  1449. X        printid(defnams[dfalse]^.lid);
  1450. X        writeln(');');
  1451. X        writeln(tab2, 'j--;');
  1452. X        writeln(tab1, '}');
  1453. X        write(tab1, 'return (');
  1454. X        printid(defnams[dtrue]^.lid);
  1455. X        writeln(');');
  1456. X        writeln('}')
  1457. X        end;
  1458. X    if usesne then
  1459. X        begin
  1460. X        writeln;
  1461. X        write(static);
  1462. X        printid(defnams[dboolean]^.lid);
  1463. X        writeln;
  1464. X        writeln('Ne(p1, p2)');
  1465. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1466. X        writeln('{');
  1467. X        write(tab1, 'return (!Eq(p1, p2));');
  1468. X        writeln('}')
  1469. X        end;
  1470. X    if usesle then
  1471. X        begin
  1472. X        writeln;
  1473. X        write(static);
  1474. X        printid(defnams[dboolean]^.lid);
  1475. X        writeln;
  1476. X        writeln('Le(p1, p2)');
  1477. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1478. X        writeln('{');
  1479. X        writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1480. X        writeln;
  1481. X        writeln(tab1, 'i = *p1++;');
  1482. X        writeln(tab1, 'j = *p2++;');
  1483. X        writeln(tab1, 'while (i != 0 && j != 0) {');
  1484. X        writeln(tab2, 'if ((*p1++ & ~ *p2++) != 0)');
  1485. X        write(tab3, 'return (');
  1486. X        printid(defnams[dfalse]^.lid);
  1487. X        writeln(');');
  1488. X        writeln(tab2, 'i--, j--;');
  1489. X        writeln(tab1, '}');
  1490. X        writeln(tab1, 'while (i != 0) {');
  1491. X        writeln(tab2, 'if (*p1++ != 0)');
  1492. X        write(tab3, 'return (');
  1493. X        printid(defnams[dfalse]^.lid);
  1494. X        writeln(');');
  1495. X        writeln(tab2, 'i--;');
  1496. X        writeln(tab1, '}');
  1497. X        write(tab1, 'return (');
  1498. X        printid(defnams[dtrue]^.lid);
  1499. X        writeln(');');
  1500. X        writeln('}')
  1501. X        end;
  1502. X    if usesge then
  1503. X        begin
  1504. X        writeln;
  1505. X        write(static);
  1506. X        printid(defnams[dboolean]^.lid);
  1507. X        writeln;
  1508. X        writeln('Ge(p1, p2)');
  1509. X        writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1510. X        writeln('{');
  1511. X        writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1512. X        writeln;
  1513. X        writeln(tab1, 'i = *p1++;');
  1514. X        writeln(tab1, 'j = *p2++;');
  1515. X        writeln(tab1, 'while (i != 0 && j != 0) {');
  1516. X        writeln(tab2, 'if ((*p2++ & ~ *p1++) != 0)');
  1517. X        writeln(tab3, 'return (false);');
  1518. X        writeln(tab2, 'i--, j--;');
  1519. X        writeln(tab1, '}');
  1520. X        writeln(tab1, 'while (j != 0) {');
  1521. X        writeln(tab2, 'if (*p2++ != 0)');
  1522. X        write(tab3, 'return (');
  1523. X        printid(defnams[dfalse]^.lid);
  1524. X        writeln(');');
  1525. X        writeln(tab2, 'j--;');
  1526. X        writeln(tab1, '}');
  1527. X        write(tab1, 'return (');
  1528. X        printid(defnams[dtrue]^.lid);
  1529. X        writeln(');');
  1530. X        writeln('}')
  1531. X        end;
  1532. X    if usemksub then
  1533. X        begin
  1534. X        writeln;
  1535. X        writeln(static, setptyp);
  1536. X        writeln('Mksubr(lo, hi, sp)');
  1537. X        writeln(tab1, registr, usigned, inttyp, tab1, 'lo, hi;');
  1538. X        writeln(tab1, registr, setptyp, tab1, 'sp;');
  1539. X        writeln('{');
  1540. X        writeln(tab1, registr, inttyp, tab1, 'i, k;');
  1541. X        writeln;
  1542. X        writeln(tab1, 'if (hi < lo)');
  1543. X        writeln(tab2, 'return (sp);');
  1544. X        writeln(tab1, 'i = hi / (setbits+1) + 1;');
  1545. X        writeln(tab1, 'for (k = *sp + 1; k <= i; k++)');
  1546. X        writeln(tab2, 'sp[k] = 0;');
  1547. X        writeln(tab1, 'if (*sp < i)');
  1548. X        writeln(tab2, '*sp = i;');
  1549. X        writeln(tab1, 'for (k = lo; k <= hi; k++)');
  1550. X        writeln(tab2, 'sp[k / (setbits+1) + 1] |= ',
  1551. X                        '(1 << (k % (setbits+1)));');
  1552. X        writeln(tab1, 'return (sp);');
  1553. X        writeln('}')
  1554. X        end;
  1555. X    if useins then
  1556. X        begin
  1557. X        writeln;
  1558. X        writeln(static, setptyp);
  1559. X        writeln('Insmem(m, sp)');
  1560. X        writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1561. X        writeln(tab1, registr, setptyp, tab1, 'sp;');
  1562. X        writeln('{');
  1563. X        writeln(tab1, registr, inttyp, tab1, 'i,');
  1564. X        writeln(tab3, tab1, 'j = m / (setbits+1) + 1;');
  1565. X        writeln;
  1566. X        writeln(tab1, 'if (*sp < j)');
  1567. X        writeln(tab2, 'for (i = *sp + 1, *sp = j; i <= *sp; i++)');
  1568. X        writeln(tab3, 'sp[i] = 0;');
  1569. X        writeln(tab1, 'sp[j] |= (1 << (m % (setbits+1)));');
  1570. X        writeln(tab1, 'return (sp);');
  1571. X        writeln('}')
  1572. X        end;
  1573. X    if usesets then
  1574. X        begin
  1575. X        writeln;
  1576. X        writeln(ifndef, 'SETSPACE');
  1577. X        writeln(define, 'SETSPACE 256');
  1578. X        writeln(endif);
  1579. X        writeln(static, setptyp);
  1580. X        writeln('Currset(n,sp)');
  1581. X        writeln(tab1, inttyp, tab1, 'n;');
  1582. X        writeln(tab1, setptyp, tab1, 'sp;');
  1583. X        writeln('{');
  1584. X        writeln(tab1, static, setwtyp, tab1, 'Space[SETSPACE];');
  1585. X        writeln(tab1, static, setptyp, tab1, 'Top = Space;');
  1586. X        writeln;
  1587. X        writeln(tab1, 'switch (n) {');
  1588. X        writeln(tab1, '  case 0:');
  1589. X        writeln(tab2, 'Top = Space;');
  1590. X        writeln(tab2, 'return (0);');
  1591. X        writeln(tab1, '  case 1:');
  1592. X        writeln(tab2, 'if (&Space[SETSPACE] - Top <= ',
  1593. X                            maxsetrange:1, ') {');
  1594. X        writeln(tab3,
  1595. X            voidcast, 'fprintf(stderr, "Set-space exhausted\n");');
  1596. X        writeln(tab3, 'exit(1);');
  1597. X        writeln(tab2, '}');
  1598. X        writeln(tab2, '*Top = 0;');
  1599. X        writeln(tab2, 'return (Top);');
  1600. X        writeln(tab1, '  case 2:');
  1601. X        writeln(tab2, 'if (Top <= &sp[*sp])');
  1602. X        writeln(tab3, 'Top = &sp[*sp + 1];');
  1603. X        writeln(tab2, 'return (sp);');
  1604. X        writeln(tab1, '}');
  1605. X        writeln(tab1, '/', '* NOTREACHED *', '/');
  1606. X        writeln('}')
  1607. X        end;
  1608. X    if usescpy then
  1609. X        begin
  1610. X        writeln;
  1611. X        writeln(static, voidtyp);
  1612. X        writeln('Setncpy(S1, S2, N)');
  1613. X        writeln(tab1, registr, setptyp, tab1, 'S1, S2;');
  1614. X        writeln(tab1, registr, usigned, inttyp, tab1, 'N;');
  1615. X        writeln('{');
  1616. X        writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1617. X        writeln;
  1618. X        writeln(tab1, 'N /= sizeof(', setwtyp, ');');
  1619. X        writeln(tab1, '*S1++ = --N;');
  1620. X        writeln(tab1, 'm = *S2++;');
  1621. X        writeln(tab1, 'while (m != 0 && N != 0) {');
  1622. X        writeln(tab2, '*S1++ = *S2++;');
  1623. X        writeln(tab2, '--N;');
  1624. X        writeln(tab2, '--m;');
  1625. X        writeln(tab1, '}');
  1626. X        writeln(tab1, 'while (N-- != 0)');
  1627. X        writeln(tab2, '*S1++ = 0;');
  1628. X        writeln('}')
  1629. X        end;
  1630. X    if usecase then
  1631. X        begin
  1632. X        writeln;
  1633. X        writeln(static, voidtyp);
  1634. X        writeln('Caseerror(n)');
  1635. X        writeln(tab1, inttyp, tab1, 'n;');
  1636. X        writeln('{');
  1637. X        writeln(tab1, voidcast,
  1638. X            'fprintf(stderr, "Missing case limb: line %d\n", n);');
  1639. X        writeln(tab1, 'exit(1);');
  1640. X        writeln('}')
  1641. X        end;
  1642. X    if usemax then
  1643. X        begin
  1644. X        writeln;
  1645. X        writeln(static, inttyp);
  1646. X        writeln('Max(m, n)');
  1647. X        writeln(tab1, inttyp, tab1, 'm, n;');
  1648. X        writeln('{');
  1649. X        writeln(tab1, 'if (m > n)');
  1650. X        writeln(tab2, 'return (m);');
  1651. X        writeln(tab1, 'return (n);');
  1652. X        writeln('}')
  1653. X        end;
  1654. X    if use(dtrunc) then
  1655. X        begin
  1656. X        writeln(static, inttyp);
  1657. X        writeln('Trunc(f)');
  1658. X        printid(defnams[dreal]^.lid);
  1659. X        writeln(tab1, 'f;');
  1660. X        writeln('{');
  1661. X        writeln(tab1, 'return f;');
  1662. X        writeln('}')
  1663. X        end;
  1664. X    if use(dround) then
  1665. X        begin
  1666. X        writeln(static, inttyp);
  1667. X        writeln('Round(f)');
  1668. X        printid(defnams[dreal]^.lid);
  1669. X        writeln(tab1, 'f;');
  1670. X        writeln('{');
  1671. X        writeln(tab1, xtern, doubletyp, ' floor();');    (* LIB *)
  1672. X        writeln(tab1,
  1673. X            'return floor(', dblcast, '(0.5+f));');    (* LIB *)
  1674. X        writeln('}')
  1675. X        end
  1676. Xend;    (* emit *)
  1677. X
  1678. X(*    Initialize all global structures used in translator.        *)
  1679. Xprocedure initialize;
  1680. X
  1681. Xvar    s    : hashtyp;
  1682. X    t    : pretyps;
  1683. X    d    : predefs;
  1684. X
  1685. X    (*    Define names in ctable.                    *)
  1686. X    procedure defname(cn : cnames; str : keyword);
  1687. X
  1688. X    label    999;
  1689. X
  1690. X    var    w    : toknbuf;
  1691. X        i    : toknidx;
  1692. X
  1693. X    begin
  1694. X        unpack(str, w, 1);
  1695. X        for i := 1 to keywordlen do
  1696. X            if w[i] = space then
  1697. X                begin
  1698. X                w[i] := chr(null);
  1699. X                goto 999
  1700. X                end;
  1701. X        w[keywordlen+1] := chr(null);
  1702. X    999:
  1703. X        ctable[cn] := saveid(w)
  1704. X    end;
  1705. X
  1706. X    (*    Define predefined identifiers.                *)
  1707. X    procedure defid(nt : treetyp; did : predefs; str : keyword);
  1708. X
  1709. X    label    999;
  1710. X
  1711. X    var    w    : toknbuf;
  1712. X        i    : toknidx;
  1713. X        tp, tq,
  1714. X        tv    : treeptr;
  1715. X
  1716. X    begin
  1717. X        for i := 1 to keywordlen do
  1718. X            if str[i] = space then
  1719. X                begin
  1720. X                w[i] := chr(null);
  1721. X                goto 999
  1722. X                end
  1723. X            else
  1724. X                w[i] := str[i];
  1725. X        w[keywordlen+1] := chr(null);
  1726. X    999:
  1727. X        tp := newid(saveid(w));
  1728. X        defnams[did] := tp^.tsym;
  1729. X        if nt in [ntype, nfunc, nproc] then
  1730. X            begin
  1731. X            (* predefined types, procedures and functions
  1732. X                are marked with a particular node *)
  1733. X            tv := mknode(npredef);
  1734. X            tv^.tdef := did;
  1735. X            tv^.tobtyp := tnone
  1736. X            end
  1737. X        else
  1738. X            tv := nil; (* predefined constants and variables will
  1739. X                    eventually be bound to something *)
  1740. X        case nt of
  1741. X          nscalar:
  1742. X            begin
  1743. X            tv := mknode(nscalar);
  1744. X            tv^.tscalid := nil;
  1745. X            tq := mknode(ntype);
  1746. X            tq^.tbind := tv;
  1747. X            tq^.tidl := tp;
  1748. X            tp := tq
  1749. X            end;
  1750. X          nconst,
  1751. X          ntype,
  1752. X          nfield,
  1753. X          nvar:
  1754. X            begin
  1755. X            tq := mknode(nt);
  1756. X            tq^.tbind := tv;
  1757. X            tq^.tidl := tp;
  1758. X            tq^.tattr := anone;
  1759. X            tp := tq
  1760. X            end;
  1761. X          nfunc,
  1762. X          nproc:
  1763. X            begin
  1764. X            tq := mknode(nt);
  1765. X            tq^.tsubid := tp;
  1766. X            tq^.tsubstmt := tv;
  1767. X            tq^.tfuntyp := nil;
  1768. X            tq^.tsubpar := nil;
  1769. X            tq^.tsublab := nil;
  1770. X            tq^.tsubconst := nil;
  1771. X            tq^.tsubtype := nil;
  1772. X            tq^.tsubvar := nil;
  1773. X            tq^.tsubsub := nil;
  1774. X            tq^.tscope := nil;
  1775. X            tq^.tstat := 0;
  1776. X            tp := tq
  1777. X            end;
  1778. X          nid:
  1779. X        end;(* case *)
  1780. X        deftab[did] := tp
  1781. X    end;    (* defid *)
  1782. X
  1783. X    (*    Define keywords.                    *)
  1784. X    procedure defkey(s : symtyp; w : keyword);
  1785. X
  1786. X    var    i    : 1 .. keywordlen;
  1787. X
  1788. X    begin
  1789. X        for i := 1 to keywordlen do
  1790. X            if w[i] = space then
  1791. X                w[i] := chr(null);
  1792. X        (* relies on symtyp being sorted *)
  1793. X        with keytab[ord(s)] do
  1794. X            begin
  1795. X            wrd := w;
  1796. X            sym := s
  1797. X            end;
  1798. X    end;
  1799. X
  1800. X    procedure fixinit(i : strindx);
  1801. X
  1802. X    var    t    : toknbuf;
  1803. X
  1804. X    begin
  1805. X        gettokn(i, t);
  1806. X        t[1] := 'i';
  1807. X        puttokn(i, t);
  1808. X    end;
  1809. X
  1810. X    (*    Add a cpu word type description.            *)
  1811. X    (*    Parameters lo and hi gives the range of a machine-    *)
  1812. X    (*    dependant integer type. Parameter str gives the corres-    *)
  1813. X    (*    ponding C-language type-name.                *)
  1814. X    procedure defmach(lo, hi : integer; str : machdefstr);
  1815. X
  1816. X    label    999;
  1817. X
  1818. X    var    i    : toknidx;
  1819. X        w    : toknbuf;
  1820. X
  1821. X    begin
  1822. X        unpack(str, w, 1);
  1823. X        if w[machdeflen] <> space then
  1824. X            error(ebadmach);
  1825. X        for i := machdeflen - 1 downto 1 do
  1826. X            if w[i] <> space then
  1827. X                begin
  1828. X                w[i+1] := chr(null);
  1829. X                goto 999
  1830. X                end;
  1831. X        error(ebadmach);
  1832. X    999:
  1833. X        if nmachdefs >= maxmachdefs then
  1834. X            error(emanymachs);
  1835. X        nmachdefs := nmachdefs + 1;
  1836. X        with machdefs[nmachdefs] do
  1837. X            begin
  1838. X            lolim := lo;
  1839. X            hilim := hi;
  1840. X            typstr := savestr(w)
  1841. X            end
  1842. X    end;
  1843. X
  1844. X    procedure initstrstore;
  1845. X
  1846. X    var    i    : strbcnt;
  1847. X
  1848. X    begin
  1849. X        for i := 1 to maxblkcnt do
  1850. X            strstor[i] := nil;
  1851. X        new(strstor[0]);
  1852. X        strstor[0]^[0] := chr(null);
  1853. X        strfree := 1;
  1854. X        strleft := maxstrblk
  1855. X    end;
  1856. X
  1857. Xbegin    (* initialize *)
  1858. X    lineno := 1;
  1859. X    colno := 0;
  1860. X
  1861. X    initstrstore;
  1862. X
  1863. X    setlst := nil;
  1864. X    setcnt := 0;
  1865. X    hexdig := '0123456789ABCDEF';
  1866. X
  1867. X    symtab := nil;
  1868. X    statlvl := 0;
  1869. X    maxlevel := -1;
  1870. X    enterscope(nil);
  1871. X    varno:= 0;
  1872. X
  1873. X    usenilp := false;
  1874. X
  1875. X    usesets := false;
  1876. X    useunion := false;
  1877. X    usediff := false;
  1878. X    usemksub := false;
  1879. X    useintr := false;
  1880. X    usesge := false;
  1881. X    usesle := false;
  1882. X    usesne := false;
  1883. X    useseq := false;
  1884. X    usememb := false;
  1885. X    useins := false;
  1886. X    usescpy := false;
  1887. X    usefopn := false;
  1888. X    usescan := false;
  1889. X    usegetl := false;
  1890. X
  1891. X    usecase := false;
  1892. X    usejmps := false;
  1893. X
  1894. X    usebool := false;
  1895. X
  1896. X    usecomp := false;
  1897. X    usemax    := false;
  1898. X
  1899. X    for s := 0 to hashmax do
  1900. X        idtab[s] := nil;
  1901. X    for d := dabs to dztring do
  1902. X        begin
  1903. X        deftab[d] := nil;
  1904. X        defnams[d] := nil
  1905. X        end;
  1906. X
  1907. X    (* Pascal keywords *)
  1908. X    defkey(sand,    'and       ');
  1909. X    defkey(sarray,    'array     ');
  1910. X    defkey(sbegin,    'begin     ');
  1911. X    defkey(scase,    'case      ');
  1912. X    defkey(sconst,    'const     ');
  1913. X    defkey(sdiv,    'div       ');
  1914. X    defkey(sdo,    'do        ');
  1915. X    defkey(sdownto,    'downto    ');
  1916. X    defkey(selse,    'else      ');
  1917. X    defkey(send,    'end       ');
  1918. X    defkey(sextern,    externsym);    (* non-standard *)
  1919. X    defkey(sfile,    'file      ');
  1920. X    defkey(sfor,    'for       ');
  1921. X    defkey(sforward,'forward   ');
  1922. X    defkey(sfunc,    'function  ');
  1923. X    defkey(sgoto,    'goto      ');
  1924. X    defkey(sif,    'if        ');
  1925. X    defkey(sinn,    'in        ');
  1926. X    defkey(slabel,    'label     ');
  1927. X    defkey(smod,    'mod       ');
  1928. X    defkey(snil,    'nil       ');
  1929. X    defkey(snot,    'not       ');
  1930. X    defkey(sof,    'of        ');
  1931. X    defkey(sor,    'or        ');
  1932. X    defkey(sother,    othersym);    (* non-standard *)
  1933. X    defkey(spacked,    'packed    ');
  1934. X    defkey(sproc,    'procedure ');
  1935. X    defkey(spgm,    'program   ');
  1936. X    defkey(srecord,    'record    ');
  1937. X    defkey(srepeat,    'repeat    ');
  1938. X    defkey(sset,    'set       ');
  1939. X    defkey(sthen,    'then      ');
  1940. X    defkey(sto,    'to        ');
  1941. X    defkey(stype,    'type      ');
  1942. X    defkey(suntil,    'until     ');
  1943. X    defkey(svar,    'var       ');
  1944. X    defkey(swhile,    'while     ');
  1945. X    defkey(swith,    'with      ');
  1946. X    defkey(seof,    dummysym);    (* dummy entry *)
  1947. X
  1948. X    (* C language operator priorities *)
  1949. X    cprio[nformat]    := 0;
  1950. X    cprio[nrange]    := 0;
  1951. X    cprio[nin]    := 0;
  1952. X    cprio[nset]    := 0;
  1953. X    cprio[nassign]    := 0;
  1954. X    cprio[nor]    := 1;
  1955. X    cprio[nand]    := 2;
  1956. X    cprio[neq]    := 3;
  1957. X    cprio[nne]    := 3;
  1958. X    cprio[nlt]    := 3;
  1959. X    cprio[nle]    := 3;
  1960. X    cprio[ngt]    := 3;
  1961. X    cprio[nge]    := 3;
  1962. X    cprio[nplus]    := 4;
  1963. X    cprio[nminus]    := 4;
  1964. X    cprio[nmul]    := 5;
  1965. X    cprio[ndiv]    := 5;
  1966. X    cprio[nmod]    := 5;
  1967. X    cprio[nquot]    := 5;
  1968. X    cprio[nnot]    := 6;
  1969. X    cprio[numinus]    := 6;
  1970. X    cprio[nuplus]    := 7;
  1971. X    cprio[nindex]    := 7;
  1972. X    cprio[nselect]    := 7;
  1973. X    cprio[nderef]    := 7;
  1974. X    cprio[ncall]    := 7;
  1975. X    cprio[nid]    := 7;
  1976. X    cprio[nchar]    := 7;
  1977. X    cprio[ninteger]    := 7;
  1978. X    cprio[nreal]    := 7;
  1979. X    cprio[nstring]    := 7;
  1980. X    cprio[nnil]    := 7;
  1981. X
  1982. X    (* Pascal language operator priorities *)
  1983. X    pprio[nassign]    := 0;
  1984. X    pprio[nformat]    := 0;
  1985. X    pprio[nrange]    := 1;
  1986. X    pprio[nin]    := 1;
  1987. X    pprio[neq]    := 1;
  1988. X    pprio[nne]    := 1;
  1989. X    pprio[nlt]    := 1;
  1990. X    pprio[nle]    := 1;
  1991. X    pprio[ngt]    := 1;
  1992. X    pprio[nge]    := 1;
  1993. X    pprio[nor]    := 2;
  1994. X    pprio[nplus]    := 2;
  1995. X    pprio[nminus]    := 2;
  1996. X    pprio[nand]    := 3;
  1997. X    pprio[nmul]    := 3;
  1998. X    pprio[ndiv]    := 3;
  1999. X    pprio[nmod]    := 3;
  2000. X    pprio[nquot]    := 3;
  2001. X    pprio[nnot]    := 4;
  2002. X    pprio[numinus]    := 4;
  2003. X    pprio[nuplus]    := 5;
  2004. X    pprio[nset]    := 6;
  2005. X    pprio[nindex]    := 6;
  2006. X    pprio[nselect]    := 6;
  2007. X    pprio[nderef]    := 6;
  2008. X    pprio[ncall]    := 6;
  2009. X    pprio[nid]    := 6;
  2010. X    pprio[nchar]    := 6;
  2011. X    pprio[ninteger]    := 6;
  2012. X    pprio[nreal]    := 6;
  2013. X    pprio[nstring]    := 6;
  2014. X    pprio[nnil]    := 6;
  2015. X
  2016. X    (* table of C keywords/functions (which Pascal doesn't know about) *)
  2017. X    defname(cabort,        'abort     ');    (* OS *)
  2018. X    defname(cbreak,        'break     ');
  2019. X    defname(ccontinue,    'continue  ');
  2020. X    defname(cdefine,    'define    ');
  2021. X    defname(cdefault,    'default   ');
  2022. X    defname(cdouble,    'double    ');
  2023. X    defname(cedata,        'edata     ');    (* OS *)
  2024. X    defname(cenum,        'enum      ');
  2025. X    defname(cetext,        'etext     ');    (* OS *)
  2026. X    defname(cextern,    'extern    ');
  2027. X    defname(cfclose,    'fclose    ');    (* LIB *)
  2028. X    defname(cfflush,    'fflush    ');    (* LIB *)
  2029. X    defname(cfgetc,        'fgetc     ');    (* LIB *)
  2030. X    defname(cfloat,        'float     ');
  2031. X    defname(cfloor,        'floor     ');    (* OS *)
  2032. X    defname(cfprintf,    'fprintf   ');    (* LIB *)
  2033. X    defname(cfputc,        'fputc     ');    (* LIB *)
  2034. X    defname(cfread,        'fread     ');    (* LIB *)
  2035. X    defname(cfscanf,    'fscanf    ');    (* LIB *)
  2036. X    defname(cfwrite,    'fwrite    ');    (* LIB *)
  2037. X    defname(cgetc,        'getc      ');    (* OS *)
  2038. X    defname(cgetpid,    'getpid    ');    (* OS *)
  2039. X    defname(cint,        'int       ');
  2040. X    defname(cinclude,    'include   ');
  2041. X    defname(clong,        'long      ');
  2042. X    defname(clog,        'log       ');    (* OS *)
  2043. X    defname(cmain,        'main      ');
  2044. X    defname(cmalloc,    'malloc    ');    (* LIB *)
  2045. X    defname(cprintf,    'printf    ');    (* LIB *)
  2046. X    defname(cpower,        'pow       ');    (* OS *)
  2047. X    defname(cputc,        'putc      ');    (* LIB *)
  2048. X    defname(cread,        'read      ');    (* OS *)
  2049. X    defname(creturn,    'return    ');
  2050. X    defname(cregister,    'register  ');
  2051. X    defname(crewind,    'rewind    ');    (* LIB *)
  2052. X    defname(cscanf,        'scanf     ');    (* LIB *)
  2053. X    defname(csetbits,    'setbits   ');
  2054. X    defname(csetword,    'setword   ');
  2055. X    defname(csetptr,    'setptr    ');
  2056. X    defname(cshort,        'short     ');
  2057. X    defname(csigned,    'signed    ');
  2058. X    defname(csizeof,    'sizeof    ');
  2059. X    defname(csprintf,    'sprintf   ');    (* LIB *)
  2060. X    defname(cstatic,    'static    ');
  2061. X    defname(cstdin,        'stdin     ');    (* LIB *)
  2062. X    defname(cstdout,    'stdout    ');    (* LIB *)
  2063. X    defname(cstderr,    'stderr    ');    (* LIB *)
  2064. X    defname(cstrncmp,    'strncmp   ');    (* OS *)
  2065. X    defname(cstrncpy,    'strncpy   ');    (* OS *)
  2066. X    defname(cstruct,    'struct    ');
  2067. X    defname(cswitch,    'switch    ');
  2068. X    defname(ctypedef,    'typedef   ');
  2069. X    defname(cundef,        'undef     ');
  2070. X    defname(cungetc,    'ungetc    ');    (* LIB *)
  2071. X    defname(cunion,        'union     ');
  2072. X    defname(cunlink,    'unlink    ');    (* OS *)
  2073. X    defname(cunsigned,    'unsigned  ');
  2074. X    defname(cwrite,        'write     ');    (* OS *)
  2075. X
  2076. X    (* create predefined identifiers *)
  2077. X    defid(nfunc,    dabs,        'abs       ');
  2078. X    defid(nfunc,    darctan,    'arctan    ');
  2079. X    defid(nvar,    dargc,        'argc      ');    (* OS *)
  2080. X    defid(nproc,    dargv,        'argv      ');    (* OS *)
  2081. X    defid(nscalar,    dboolean,    'boolean   ');
  2082. X    defid(ntype,    dchar,        'char      ');
  2083. X    defid(nfunc,    dchr,        'chr       ');
  2084. X    defid(nproc,    dclose,        'close     ');    (* OS *)
  2085. X    defid(nfunc,    dcos,        'cos       ');
  2086. X    defid(nproc,    ddispose,    'dispose   ');
  2087. X    defid(nid,    dfalse,        'false     ');
  2088. X    defid(nfunc,    deof,        'eof       ');
  2089. X    defid(nfunc,    deoln,        'eoln      ');
  2090. X    defid(nproc,    dexit,        'exit      ');    (* OS *)
  2091. X    defid(nfunc,    dexp,        'exp       ');
  2092. X    defid(nproc,    dflush,        'flush     ');    (* OS *)
  2093. X    defid(nproc,    dget,        'get       ');
  2094. X    defid(nproc,    dhalt,        'halt      ');    (* OS *)
  2095. X    defid(nvar,    dinput,        'input     ');
  2096. X    defid(ntype,    dinteger,    'integer   ');
  2097. X    defid(nfunc,    dln,        'ln        ');
  2098. X    defid(nconst,    dmaxint,    'maxint    ');
  2099. X    defid(nproc,    dmessage,    'message   ');    (* OS *)
  2100. X    defid(nproc,    dnew,        'new       ');
  2101. X    defid(nfunc,    dodd,        'odd       ');
  2102. X    defid(nfunc,    dord,        'ord       ');
  2103. X    defid(nvar,    doutput,    'output    ');
  2104. X    defid(nproc,    dpack,        'pack      ');
  2105. X    defid(nproc,    dpage,        'page      ');
  2106. X    defid(nfunc,    dpred,        'pred      ');
  2107. X    defid(nproc,    dput,        'put       ');
  2108. X    defid(nproc,    dread,        'read      ');
  2109. X    defid(nproc,    dreadln,    'readln    ');
  2110. X    defid(ntype,    dreal,        'real      ');
  2111. X    defid(nproc,    dreset,        'reset     ');
  2112. X    defid(nproc,    drewrite,    'rewrite   ');
  2113. X    defid(nfunc,    dround,        'round     ');
  2114. X    defid(nfunc,    dsin,        'sin       ');
  2115. X    defid(nfunc,    dsqr,        'sqr       ');
  2116. X    defid(nfunc,    dsqrt,        'sqrt      ');
  2117. X    defid(nfunc,    dsucc,        'succ      ');
  2118. X    defid(ntype,    dtext,        'text      ');
  2119. X    defid(nid,    dtrue,        'true      ');
  2120. X    defid(nfunc,    dtrunc,        'trunc     ');
  2121. X    defid(nfunc,    dtan,        'tan       ');
  2122. X    defid(nproc,    dunpack,    'unpack    ');
  2123. X    defid(nproc,    dwrite,        'write     ');
  2124. X    defid(nproc,    dwriteln,    'writeln   ');
  2125. X
  2126. X    defid(nfield,    dzinit,        '$nit      ');    (* for internal use *)
  2127. X    defid(ntype,    dztring,    '$ztring   ');
  2128. X
  2129. X    (* bind constants and variables *)
  2130. X    deftab[dboolean]^.tbind^.tscalid := deftab[dfalse];
  2131. X    deftab[dfalse]^.tnext := deftab[dtrue];
  2132. X    currsym.st := sinteger;
  2133. X    currsym.vint := maxint;
  2134. X    deftab[dmaxint]^.tbind := mklit;
  2135. X    deftab[dargc]^.tbind := deftab[dinteger]^.tbind;
  2136. X    deftab[dinput]^.tbind := deftab[dtext]^.tbind;
  2137. X    deftab[doutput]^.tbind := deftab[dtext]^.tbind;
  2138. X
  2139. X    for t := tnone to terror do
  2140. X        begin
  2141. X        (* for predefined types: set up pointers to "npredef" nodes
  2142. X           describing type, fill in constant identifying type *)
  2143. X        case t of
  2144. X          tboolean:
  2145. X            typnods[t] := deftab[dboolean]; (* scalar type *)
  2146. X          tchar:
  2147. X            typnods[t] := deftab[dchar]^.tbind;
  2148. X          tinteger:
  2149. X            typnods[t] := deftab[dinteger]^.tbind;
  2150. X          treal:
  2151. X            typnods[t] := deftab[dreal]^.tbind;
  2152. X          ttext:
  2153. X            typnods[t] := deftab[dtext]^.tbind;
  2154. X          tstring:
  2155. X            typnods[t] := deftab[dztring]^.tbind;
  2156. X          tnil,
  2157. X          tset,
  2158. X          tpoly,
  2159. X          tnone:
  2160. X            typnods[t] := mknode(npredef);
  2161. X          terror:
  2162. X            (* no op *)
  2163. X        end;(* case *)
  2164. X        if t in [tchar, tinteger, treal, ttext, tnone, tpoly,
  2165. X                        tstring, tnil, tset] then
  2166. X            typnods[t]^.tobtyp := t
  2167. X        end;
  2168. X
  2169. X    (* fix name and type of field "init" *)
  2170. X    fixinit(defnams[dzinit]^.lid^.istr);
  2171. X    deftab[dzinit]^.tbind := deftab[dinteger]^.tbind;
  2172. X
  2173. X    for d := dabs to dztring do
  2174. X        linkup(nil, deftab[d]);
  2175. X
  2176. X    deftab[dchr]^.tfuntyp := typnods[tchar];
  2177. X
  2178. X    deftab[deof]^.tfuntyp := typnods[tboolean];
  2179. X    deftab[deoln]^.tfuntyp := typnods[tboolean];
  2180. X    deftab[dodd]^.tfuntyp := typnods[tboolean];
  2181. X
  2182. X    deftab[dord]^.tfuntyp := typnods[tinteger];
  2183. X    deftab[dround]^.tfuntyp := typnods[tinteger];
  2184. X    deftab[dtrunc]^.tfuntyp := typnods[tinteger];
  2185. X
  2186. X    deftab[darctan]^.tfuntyp := typnods[treal];
  2187. X    deftab[dcos]^.tfuntyp := typnods[treal];
  2188. X    deftab[dsin]^.tfuntyp := typnods[treal];
  2189. X    deftab[dtan]^.tfuntyp := typnods[treal];
  2190. X    deftab[dsqrt]^.tfuntyp := typnods[treal];
  2191. X    deftab[dexp]^.tfuntyp := typnods[treal];
  2192. X    deftab[dln]^.tfuntyp := typnods[treal];
  2193. X
  2194. X    deftab[dsqr]^.tfuntyp := typnods[tpoly];
  2195. X    deftab[dabs]^.tfuntyp := typnods[tpoly];
  2196. X    deftab[dpred]^.tfuntyp := typnods[tpoly];
  2197. X    deftab[dsucc]^.tfuntyp := typnods[tpoly];
  2198. X
  2199. X    deftab[dargv]^.tfuntyp := typnods[tnone];
  2200. X    deftab[ddispose]^.tfuntyp := typnods[tnone];
  2201. X    deftab[dexit]^.tfuntyp := typnods[tnone];
  2202. X    deftab[dget]^.tfuntyp := typnods[tnone];
  2203. X    deftab[dhalt]^.tfuntyp := typnods[tnone];
  2204. X    deftab[dnew]^.tfuntyp := typnods[tnone];
  2205. X    deftab[dpack]^.tfuntyp := typnods[tnone];
  2206. X    deftab[dput]^.tfuntyp := typnods[tnone];
  2207. X    deftab[dread]^.tfuntyp := typnods[tnone];
  2208. X    deftab[dreadln]^.tfuntyp := typnods[tnone];
  2209. X    deftab[dreset]^.tfuntyp := typnods[tnone];
  2210. X    deftab[drewrite]^.tfuntyp := typnods[tnone];
  2211. X    deftab[dwrite]^.tfuntyp := typnods[tnone];
  2212. X    deftab[dwriteln]^.tfuntyp := typnods[tnone];
  2213. X    deftab[dmessage]^.tfuntyp := typnods[tnone];
  2214. X    deftab[dunpack]^.tfuntyp := typnods[tnone];
  2215. X
  2216. X    (* set up definitions for integer subranges *)
  2217. X    nmachdefs := 0;
  2218. X    defmach(0,        255,        'unsigned char   '); (* CPU *)
  2219. X    defmach(-128,        127,        'char            '); (* CPU *)
  2220. X    defmach(0,        65535,        'unsigned short  '); (* CPU *)
  2221. X    defmach(-32768,        32767,        'short           '); (* CPU *)
  2222. X    defmach(-2147483647,    2147483647,    'long            '); (* CPU *)
  2223. X{    defmach(0,        4294967295,    'unsigned long   ');}(* CPU *)
  2224. Xend;    (* initialize *)
  2225. X
  2226. Xprocedure exit(i : integer); external;    (* OS *)
  2227. X
  2228. X(*    Action to take when an error is detected.            *)
  2229. Xprocedure error;
  2230. X
  2231. Xbegin
  2232. X    prtmsg(m);
  2233. X    exit(1);    (* OS *)
  2234. X    goto 9999
  2235. Xend;
  2236. X
  2237. X(*    Action to take when a fatal error is detected.            *)
  2238. Xprocedure fatal;
  2239. X
  2240. Xbegin
  2241. X    prtmsg(m);
  2242. X    halt        (* OS *)
  2243. X    (* goto 9999    *)
  2244. Xend;
  2245. X
  2246. X
  2247. Xbegin    (* program *)
  2248. X    initialize;
  2249. X    if echo then
  2250. X        writeln('# ifdef PASCAL');
  2251. X    parse;
  2252. X    if echo then
  2253. X        writeln('# else');
  2254. X    lineno := 0; lastline := 0;
  2255. X    transform;
  2256. X    emit;
  2257. X    if echo then
  2258. X        writeln('# endif');
  2259. X9999:
  2260. X    (* the very *)
  2261. Xend.
  2262. X
  2263. END_OF_FILE
  2264. if test 54467 -ne `wc -c <'ptc.p.4'`; then
  2265.     echo shar: \"'ptc.p.4'\" unpacked with wrong size!
  2266. fi
  2267. # end of 'ptc.p.4'
  2268. fi
  2269. echo shar: End of archive 11 \(of 12\).
  2270. cp /dev/null ark11isdone
  2271. MISSING=""
  2272. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  2273.     if test ! -f ark${I}isdone ; then
  2274.     MISSING="${MISSING} ${I}"
  2275.     fi
  2276. done
  2277. if test "${MISSING}" = "" ; then
  2278.     echo You have unpacked all 12 archives.
  2279.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2280. else
  2281.     echo You still need to unpack the following archives:
  2282.     echo "        " ${MISSING}
  2283. fi
  2284. ##  End of shell archive.
  2285. exit 0
  2286. -- 
  2287.  
  2288. Rich $alz            "Anger is an energy"
  2289. Cronus Project, BBN Labs    rsalz@bbn.com
  2290. Moderator, comp.sources.unix    sources@uunet.uu.net
  2291.